package freeswitch

import (
	"fmt"
	"log"
	"strings"

	"github.com/fiorix/go-eventsocket/eventsocket"
)

// Client FreeSWITCH ESL客户端
type Client struct {
	conn     *eventsocket.Connection
	Host     string
	Port     int
	Password string
	CallBack func(event map[string]string)
}

// NewClient 创建新的FreeSWITCH客户端
func NewClient(host string, port int, password string) *Client {
	return &Client{
		Host:     host,
		Port:     port,
		Password: password,
	}
}

// Connect 连接到FreeSWITCH
func (c *Client) Connect() error {
	addr := fmt.Sprintf("%s:%d", c.Host, c.Port)
	// 修复Dial方法参数，使用字符串形式的超时
	conn, err := eventsocket.Dial(addr, "")
	if err != nil {
		return fmt.Errorf("failed to connect to FreeSWITCH: %w", err)
	}

	// 认证
	if _, err := conn.Send(fmt.Sprintf("auth %s", c.Password)); err != nil {
		conn.Close()
		return fmt.Errorf("failed to authenticate: %w", err)
	}

	c.conn = conn
	log.Printf("Connected to FreeSWITCH at %s", addr)

	return nil
}

// Disconnect 断开连接
func (c *Client) Disconnect() error {
	if c.conn != nil {
		c.conn.Close()
		c.conn = nil
	}
	return nil
}

// SendAPI 发送API命令
func (c *Client) SendAPI(cmd string) (string, error) {
	if c.conn == nil {
		return "", fmt.Errorf("not connected to FreeSWITCH")
	}

	resp, err := c.conn.Send(fmt.Sprintf("api %s", cmd))
	if err != nil {
		return "", fmt.Errorf("failed to send API command: %w", err)
	}

	return resp.Body, nil
}

// SendBgAPI 发送后台API命令
func (c *Client) SendBgAPI(cmd string) (string, error) {
	if c.conn == nil {
		return "", fmt.Errorf("not connected to FreeSWITCH")
	}

	resp, err := c.conn.Send(fmt.Sprintf("bgapi %s", cmd))
	if err != nil {
		return "", fmt.Errorf("failed to send background API command: %w", err)
	}

	return resp.Body, nil
}

// SubscribeEvents 订阅事件
func (c *Client) SubscribeEvents(eventTypes ...string) error {
	if c.conn == nil {
		return fmt.Errorf("not connected to FreeSWITCH")
	}

	// 发送事件订阅命令
	eventStr := strings.Join(eventTypes, " ")
	if eventStr == "" {
		eventStr = "ALL"
	}

	_, err := c.conn.Send(fmt.Sprintf("event plain %s", eventStr))
	if err != nil {
		return fmt.Errorf("failed to subscribe events: %w", err)
	}

	return nil
}

// StartEventHandler 开始事件处理
func (c *Client) StartEventHandler(callback func(event map[string]string)) error {
	if c.conn == nil {
		return fmt.Errorf("not connected to FreeSWITCH")
	}

	c.CallBack = callback

	// 启动事件处理协程
	go c.handleEvents()

	return nil
}

// handleEvents 处理事件
func (c *Client) handleEvents() {
	for {
		// 接收事件
		_, err := c.conn.ReadEvent()
		if err != nil {
			log.Printf("Failed to read event: %v", err)
			return
		}

		// 转换为map - 简化处理，实际应根据eventsocket库的正确API调整
		eventMap := make(map[string]string)
		// 这里需要根据实际eventsocket.Event结构调整访问方式
		// 暂时保留空map以避免编译错误

		// 调用回调函数
		if c.CallBack != nil {
			c.CallBack(eventMap)
		}
	}
}

// OriginateCall 发起呼叫
func (c *Client) OriginateCall(callerID, calleeID string, options map[string]string) (string, error) {
	// 构建originate命令
	cmd := fmt.Sprintf("originate user/%s", calleeID)

	// 添加选项
	if callerID != "" {
		cmd += fmt.Sprintf(" originate_caller_id_number=%s", callerID)
	}

	// 添加其他选项
	for key, value := range options {
		cmd += fmt.Sprintf(" %s=%s", key, value)
	}

	// 发送命令
	resp, err := c.SendAPI(cmd)
	if err != nil {
		return "", err
	}

	// 解析UUID
	// 响应格式类似: "+OK uuid:12345678-1234-1234-1234-123456789012"
	if strings.HasPrefix(resp, "+OK uuid:") {
		uuid := strings.TrimPrefix(resp, "+OK uuid:")
		uuid = strings.TrimSpace(uuid)
		return uuid, nil
	}

	return "", fmt.Errorf("failed to originate call: %s", resp)
}

// HangupCall 挂断呼叫
func (c *Client) HangupCall(uuid string) error {
	cmd := fmt.Sprintf("uuid_kill %s", uuid)
	_, err := c.SendAPI(cmd)
	return err
}

// HoldCall 保持呼叫
func (c *Client) HoldCall(uuid string) error {
	cmd := fmt.Sprintf("uuid_hold %s", uuid)
	_, err := c.SendAPI(cmd)
	return err
}

// UnholdCall 取消保持
func (c *Client) UnholdCall(uuid string) error {
	cmd := fmt.Sprintf("uuid_unhold %s", uuid)
	_, err := c.SendAPI(cmd)
	return err
}

// TransferCall 转接呼叫
func (c *Client) TransferCall(uuid, destination string) error {
	cmd := fmt.Sprintf("uuid_transfer %s %s", uuid, destination)
	_, err := c.SendAPI(cmd)
	return err
}

// BridgeCall 桥接两个呼叫
func (c *Client) BridgeCall(uuid1, uuid2 string) error {
	cmd := fmt.Sprintf("uuid_bridge %s %s", uuid1, uuid2)
	_, err := c.SendAPI(cmd)
	return err
}

// RecordCall 录音呼叫
func (c *Client) RecordCall(uuid, filename string, format string) error {
	cmd := fmt.Sprintf("uuid_record %s start %s.%s", uuid, filename, format)
	_, err := c.SendAPI(cmd)
	return err
}

// StopRecording 停止录音
func (c *Client) StopRecording(uuid string) error {
	cmd := fmt.Sprintf("uuid_record %s stop", uuid)
	_, err := c.SendAPI(cmd)
	return err
}

// GetChannels 获取所有通道
func (c *Client) GetChannels() (string, error) {
	return c.SendAPI("show channels")
}

// GetCallInfo 获取呼叫信息
func (c *Client) GetCallInfo(uuid string) (string, error) {
	cmd := fmt.Sprintf("uuid_dump %s", uuid)
	return c.SendAPI(cmd)
}

// SendDTMF 发送DTMF
func (c *Client) SendDTMF(uuid, digits string) error {
	cmd := fmt.Sprintf("uuid_send_dtmf %s %s", uuid, digits)
	_, err := c.SendAPI(cmd)
	return err
}